﻿package Albums 
{
	import com.greensock.TweenLite;
	import Common.AlbumDeleteMessage;
	import Common.CommonMessage;
	import Common.TextMessage;
	
	import com.junkbyte.console.Cc;	
	
	import Common.Constants;	
	import Common.ImageInfo;
	import Common.Room;
	import Common.Preloader;
	import Core.ImageContainer;
	import Core.LocalImage;
	import Core.RemoteImage;
	import Core.ImageUtils;	
	import Fonts.CalibriEmbed;
	
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.net.FileReference;
	import flash.net.URLLoader;		
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.text.engine.TextLine;
	import flash.filters.DropShadowFilter;
	/**
	 * ...
	 * @author Serg de Adelantado
	 */
	[Event(name = "album_created", type = "Albums.AlbumEvent")]
	[Event(name = "album_error", type = "Albums.AlbumEvent")]
	[Event(name = "album_updated", type = "Albums.AlbumEvent")]
	public class AlbumIcon extends AbstractIcon 
	{
		static public const SIZE:int = 130;
		
		private var FPreloader:Preloader;
		private var FBackground:Sprite;
		private var FText:TextField;		
		private var FRoom:Room;
		private var FImage:Bitmap;
		private var FLoader:Loader;
		private var FRemoteImageURL:String;
		private var FBitmap:Bitmap;
		private var FHighlite:Sprite;
		private var FTextMask:Sprite;	
		private var FTextOverlay:Sprite;
		private var FBitmapSize:Point;
		private var FInfo:ImageInfo;
		private var FIsSelected:Boolean;
		private var FShadow: DropShadowFilter;
		private var FDoDelete:Boolean;
		private var FLocal:LocalImage;
		private var FRemote:RemoteImage;		
		private var FIsRoom:Boolean;
		private var FDeleter:AlbumDeleter;		
		private var FDBLoader:URLLoader;
		//Params
		private var FName:String;
		private var FDelete:Boolean;
		private var FRoomsCount:String;
		private var FApartmentsCount:String;
		private var FInRoom:String;
		private var FAbout:String;		
		
		public function AlbumIcon() 
		{			
			useHandCursor = true;
			buttonMode = true;						
			FIsSelected = false;
			FDoDelete = false;
			FDelete = false;
			FRoomsCount = '0';
			FApartmentsCount = '0';
			FInRoom = '';
			FAbout = '';
			
			FBackground = new Sprite();
			FBackground.mouseEnabled = false;
			addChild(FBackground);	
			
			FHighlite = new Sprite();
			FHighlite.mouseEnabled = false;
			FHighlite.alpha = 0;
			addChild(FHighlite);			
			
			FWidth = new Number();
			FHeight = new Number();
			
			FPreloader = new Preloader();
			FPreloader.mouseEnabled = false;
			FPreloader.visible = false;
			addChild(FPreloader);
			
			FRemoteImageURL = '';
			
			FText = new TextField();
			FText.multiline = false;
			FText.textColor = Constants.ALBUM_TEXT;
			FText.autoSize = TextFieldAutoSize.LEFT;
			var vFormat:TextFormat = new TextFormat();
			vFormat.font = new CalibriEmbed().fontName;	
			FText.embedFonts = true;
			FText.defaultTextFormat = vFormat;
			FText.selectable = false;
			FText.mouseEnabled = false;
			addChild(FText);
			
			FTextMask = new Sprite();
			FTextMask.mouseEnabled = false;			
			addChild(FTextMask);
			FText.mask = FTextMask;
			
			FDeleter = new AlbumDeleter(this);
			
			FDBLoader = new URLLoader();			
			
			addEventListener(MouseEvent.MOUSE_OVER, OnMouseOver);
			addEventListener(MouseEvent.MOUSE_OUT, OnMouseOut);
			FShadow = new DropShadowFilter(4, -90, 0, 0.5, 0, 5, 1, 3, true);
		}
		
		public function Create(AOwner:int):void
		{
			FDBLoader.addEventListener(Event.COMPLETE, OnCreated);
			var vVars:String = '?owner_id=' + AOwner;
			vVars += '&name=Новый номер';
			FDBLoader.load(new URLRequest(Constants.ALBUM_CREATOR + vVars));
		}
		
		public function Update()
		{
			var vVars:String;
			FDBLoader.addEventListener(Event.COMPLETE, OnUpdated);
			vVars = '?id=' + FRoom.ID;
			vVars += '&name=' + FName;
			vVars += '&total=' + FRoomsCount;
			vVars += '&rooms=' + FApartmentsCount;
			vVars += '&vnomere=' + FInRoom;
			vVars += '&about=' + FAbout;
			FDBLoader.load(new URLRequest(Constants.ALBUM_UPDATER + vVars));			
		}
		
		private function ShowDelete():void 
		{
			var vMessage:AlbumDeleteMessage = new AlbumDeleteMessage();
			vMessage.Album = this;
			vMessage.Root = FViewer.Root;
			FViewer.Root.MessagesCore.Show(vMessage);
			FViewer.Root.Blur();
		}
		
		private function ShowDeleteMessage():void 
		{
			var vMessage:TextMessage = new TextMessage();			
			vMessage.Header = 'Удаление номера';
			vMessage.Description = 'Идет удаление номера. Пожалуйста, подождите.';
			FViewer.Root.MessagesCore.Show(vMessage);
			FViewer.Root.Blur();
		}
		
		public function DoDelete(ADeleteImages:Boolean = false):void
		{
			var vVars:String;
			vVars = '?id=' + FRoom.ID;
			if (ADeleteImages)
			{
				var vImages:Vector.<ImageContainer> = FViewer.ImagesByOwner(ID);
				for (var i in vImages)				
					vImages[i].MarkedForDelete = true;				
				FViewer.Uploader.DeleteAlbum(this);
			}
			else
			{		
				ShowDeleteMessage();
				FDBLoader.addEventListener(Event.COMPLETE, OnDelete);			
				FDBLoader.load(new URLRequest(Constants.ALBUM_DELETER + vVars));
			}
		}
		
		public function DoDeleteAlbum():void
		{
			ShowDeleteMessage();
			FViewer.TransferToMain(ID);	
			FDBLoader.addEventListener(Event.COMPLETE, OnDeleteAlbum);
			var vVars:String = '?id=' + FRoom.ID;
			FDBLoader.load(new URLRequest(Constants.ALBUM_DELETER + vVars));
		}
		
		private function OnDeleteAlbum(e:Event):void 
		{			
			FDBLoader.removeEventListener(Event.COMPLETE, OnDeleteAlbum);
			Remove();
			FViewer.UpdateAlbums();			
			FViewer.Uploader.Sync();
		}
		
		private function OnDelete(e:Event):void 
		{
			FDBLoader.removeEventListener(Event.COMPLETE, OnDelete);
			Remove();
			FViewer.UpdateAlbums();
		}
		
		private function Remove():void
		{			
			FViewer.Root.AlbumsTabs.Remove(this);			
			FViewer.Root.UnBlur();
			FViewer.Root.MessagesCore.visible = false;
		}
		
		private function OnCreated(e:Event):void 
		{
			FDBLoader.removeEventListener(Event.COMPLETE, OnCreated);
			var vRoom = new Room(String(FDBLoader.data), 'Новый номер');
			AlbumRoom = vRoom;
			Cc.logch('Album', 'Album with ID ' + FDBLoader.data + ' successfully created');
			dispatchEvent(new AlbumEvent(AlbumEvent.ALBUM_CREATED));
		}
		
		private function OnUpdated(e:Event):void 
		{
			FDBLoader.removeEventListener(Event.COMPLETE, OnUpdated);
			dispatchEvent(new AlbumEvent(AlbumEvent.ALBUM_UPDATED));
			Cc.logch('Album', ID + ' updated. Server response: ' + e.target.data);
		}
			
		protected function OnMouseOver(e:MouseEvent):void 
		{
			if(!FIsSelected)
				TweenLite.to(FHighlite, 0.5, { alpha: 1} );
		}
		
		protected function OnMouseOut(e:MouseEvent):void 
		{
			if(!FIsSelected)
				TweenLite.to(FHighlite, 0.5, { alpha: 0} );
		}
		
		public function ClearTitle():void
		{
			if (FBitmap)
			{				
				FBitmap.bitmapData.dispose();
				if (FBitmap.parent)
				{			
					FBitmap.parent.removeChild(FBitmap);
				}				
			}
			FRemote = null;
			FLocal = null;
			FPreloader.visible = false;
			FDoDelete = true;
		}
		
		public function Load():void
		{		
			if (FRemoteImageURL != '')
			{
				FDoDelete = false;
				FLoader = new Loader();
				FLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, OnImageLoaded);
				FLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, OnIOerror);
				FLoader.load(new URLRequest(FRemoteImageURL));
				FPreloader.visible = true;
			}
			else
				Cc.errorch('Album image', 'Can not load image: URL was not assigned');						
		}
		
		private function OnImageLoaded(e:Event):void 
		{
			e.target.removeEventListener(Event.COMPLETE, OnImageLoaded);
			e.target.removeEventListener(IOErrorEvent.IO_ERROR, OnIOerror);
			ProcessBitmap(Bitmap(e.target.content));
		}
		
		public function LoadLocal(AImage:LocalImage):void
		{
			if (!AImage.IsLoading)
			{				
				AImage.Load();
			}
			AImage.File.addEventListener(Event.COMPLETE, OnLocalFileLoaded);			
		}
		
		private function OnLocalFileLoaded(e:Event):void
		{
			e.target.removeEventListener(Event.COMPLETE, OnLocalFileLoaded);
			
			FLoader = new Loader();
			FLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, OnLocalImageLoaded);
			FLoader.loadBytes(e.target.data);
		}
		
		private function OnLocalImageLoaded(e:Event):void 
		{
			e.target.removeEventListener(Event.COMPLETE, OnLocalImageLoaded);
			ProcessBitmap(Bitmap(e.target.content));
		}
		
		protected function ProcessBitmap(ABitmap:Bitmap):void 
		{
			if (FBitmap)
			{
				FBitmap.bitmapData.dispose();
				if(FBitmap.parent == this)
					removeChild(FBitmap);				
			}			
			if (!FDoDelete)
			{
				FPreloader.visible = false;
				FBitmap = ABitmap;
				FBitmapSize = new Point(FBitmap.width, FBitmap.height);
				FBitmap.smoothing = true;
				ImageUtils.Resize(FBitmap, FWidth - 5, FHeight - FText.height - 5);
				FBitmap.x = (FWidth - FBitmap.width) / 2;			
				FBitmap.y = (FHeight - FText.height - FBitmap.height) / 2;
				FBitmap.filters = [new DropShadowFilter(0, 0, 0, 1, 10, 10, 1, 3, true)];
				addChild(FBitmap);
				addChild(FDeleter);				
			}		
			FDoDelete = false;			
			if (FLoader && FLoader.contentLoaderInfo.bytesLoaded > 0)
			{
				FLoader.contentLoaderInfo.bytes.clear();
				FLoader.unloadAndStop();
				FLoader = null;				
			}			
		}
		
		private function OnIOerror(e:IOErrorEvent):void 
		{
			e.target.removeEventListener(Event.COMPLETE, OnImageLoaded);
			e.target.removeEventListener(IOErrorEvent.IO_ERROR, OnIOerror);
			Cc.errorch('Album image', 'IOerror: ' + e.text);
			FPreloader.visible = false;
		}
		
		override protected function Draw():void 
		{
			FBackground.graphics.clear();
			FBackground.graphics.beginFill(BACKGROUND_COLOR, Constants.ALBUM_ALPHA);
			FBackground.graphics.drawRect(0, 0, FWidth, FHeight);
			FBackground.graphics.endFill();
			FHighlite.graphics.clear();
			FHighlite.graphics.beginFill(HIGHLITE_COLOR, Constants.ALBUM_HIGHLITE_ALPHA);
			FHighlite.graphics.drawRect(0, 0, FWidth, FHeight);
			FHighlite.graphics.endFill();
			
			FTextMask.graphics.clear();
			FTextMask.graphics.beginFill(BACKGROUND_COLOR, 0);
			FTextMask.graphics.drawRect(0, 0, FWidth, FHeight);
			FTextMask.graphics.endFill();
			
			FPreloader.x = (FWidth - FPreloader.width) / 2;
			FPreloader.y = (FHeight - FPreloader.height) / 2;
		}
		
		//{ Getters & setters 
			
		public function get Width():Number 
		{
			return FWidth;
		}
		
		public function set Width(AWidth:Number):void 
		{
			FWidth = AWidth;
		}
		
		public function get Height():Number 
		{
			return FHeight;
		}
		
		public function set Height(AHeight:Number):void 
		{
			FHeight = AHeight;
		}
		
		public function set AlbumRoom(ARoom:Room):void
		{
			FRoom = ARoom;			
			FText.text = FRoom.Name;
			FName = FRoom.Name;
			FRoomsCount = FRoom.Rooms;
			FApartmentsCount = FRoom.Apartments;
			FInRoom = FRoom.InRoom;
			FAbout = FRoom.About;
			Load();
		}		
		
		public function get Delete():Boolean
		{
			return FDelete;
		}
			
		public function set Delete(ADelete:Boolean):void
		{
			if (ADelete)			
				ShowDelete();			
			//FDelete = ADelete;			
		}
			
		public function get IsSelected():Boolean
		{
			return FIsSelected;
		}
		
		public function set IsSelected(ASelected:Boolean):void
		{
			FIsSelected = ASelected;
			if (FIsSelected)
			{
				TweenLite.killTweensOf(FHighlite);
				FHighlite.alpha = 0;				
				var vParent:Sprite = Sprite(parent);
				for (var i:int = 0; i < vParent.numChildren; i++)
				{
					if (vParent.getChildAt(i) != this && vParent.getChildAt(i) is AlbumIcon)
						AlbumIcon(vParent.getChildAt(i)).IsSelected = false;					
				}
				FBackground.filters = [];
				FHighlite.filters = [];
			}
			else
			{
				FBackground.filters = [FShadow];
				FHighlite.filters = [FShadow];
			}
		}
		
		public function get ID():int
		{
			var vID:int = FRoom ? FRoom.ID : -1;			
			return vID;
		}		
		
		public function get IsRoom():Boolean
		{
			return FIsRoom;
		}
		
		public function set IsRoom(AIsRoom:Boolean):void
		{
			FIsRoom = AIsRoom;
			FDeleter.visible = FIsRoom;
		}
		
		public function get Name():String
		{
			return FName;
		}
		
		public function set Name(AName:String):void
		{
			FName = AName;
			FRoom.Name = FName;
			FText.text = FName;
			SetSize(FWidth, FHeight);
		}
		
		public function get RoomsCount():String
		{
			return FRoomsCount;
		}
		
		public function set RoomsCount(value:String):void
		{
			FRoomsCount = value;
			FRoom.Rooms = value;
		}
		
		public function get ApartmentsCount():String
		{
			return FApartmentsCount;
		}
		
		public function set ApartmentsCount(value:String):void
		{
			FApartmentsCount = value;
			FRoom.Apartments = value;
		}
		
		public function get InRoom():String
		{
			return FInRoom;
		}
		
		public function set InRoom(value:String):void
		{
			FInRoom = value;
			FRoom.InRoom = value;
		}
		
		public function get About():String
		{
			return FAbout;
		}
		
		public function set About(value:String):void
		{
			FAbout = value;
			FRoom.About = value;
		}
		
		public function get AlbumRoom():Room
		{
			return FRoom;
		}
		
		public function set TitleImageFromInfo(AImage:ImageInfo):void
		{
			if (FInfo != AImage)
			{
				FDoDelete = false;
				FInfo = AImage;
				var vFile:String = Constants.IMAGES_MAIN;
				if (AImage.IsAttachedToRoom)
					vFile = Constants.IMAGES_ROOMS;	
				vFile += 'sm_' + AImage.ID.toString() + '.jpg';
				FRemoteImageURL = vFile;
			}
		}
		
		public function set TitleImageFromContainer(AImage:ImageContainer):void 
		{
			if (AImage is RemoteImage)
			{				
				if (RemoteImage(AImage) != FRemote)
				{					
					FDoDelete = false;
					FRemote = RemoteImage(AImage);
					TitleImageFromInfo = FRemote.Info;
					Load();
				}
			}
			else if (AImage is LocalImage)
			{
				if (LocalImage(AImage) != FLocal)
				{					
					FDoDelete = false;
					FLocal = LocalImage(AImage);
					LoadLocal(FLocal);
				}
			}
		}
		
		override public function SetSize(AWidth:Number, AHeight:Number):void
		{
			FWidth = AWidth;
			FHeight = AHeight;			
			Draw();			
			FText.width = FText.textWidth;
			FText.text = FName;
			if (FText.width > FWidth)
			{				
				FText.x = 0;								
				var vChar:int = FText.getCharIndexAtPoint(FWidth - 15, 5);
				var vSubstring:String = FName.substring(0, vChar);
				FText.text = vSubstring + '...';			
			}
			else
			{
				FText.x = (FWidth - FText.width) / 2;
			}
			FText.y = AHeight - FText.height;
			if (FBitmap)
			{
				FBitmap.width = FBitmapSize.x;
				FBitmap.height = FBitmapSize.y;				
				ImageUtils.Resize(FBitmap, FWidth - 5, FHeight - FText.height - 5);
				FBitmap.x = (FWidth - FBitmap.width) / 2;			
				FBitmap.y = (FHeight - FText.height * int(FText.visible) - FBitmap.height) / 2;
			}
		}
				
		//} endregion
		//End of getters & setters
	}
}